using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using MoEngine;

namespace MoGameLib
{
    public class BattleTileCollection : TileCollection<BattleTile>
    {
        public BattleTileCollection(int width, int height)
            : base(width, height)
        {
        }
    }

    public class BattleTile : IMapNode<BattleTile>
    {
        private BattleTerrainType m_TerrainType;
        private BattleGround m_Ground;
        private BattleOverlay m_Overlay;
        private BattleMap m_Map;

        public BattleTile(BattleMap map, Vector2Int location, BattleGroundType groundType, BattleOverlayType overlayType)
        {
            m_Map = map;
            m_Location = location;
            m_TerrainType = null;
            if (groundType != null)
                m_Ground = new BattleGround(this, groundType);
            if (overlayType != null)
                m_Overlay = new BattleOverlay(this, overlayType);
        }

        public BattleGround Ground
        {
            get { return m_Ground; }
        }

        public BattleOverlay Overlay
        {
            get { return m_Overlay; }
        }

        public virtual void Setup()
        {
            if (m_Ground != null)
                m_Ground.Setup();

            if (m_Overlay != null)
                m_Overlay.Setup();
        }

        private Battler m_Battler;

        public Battler Battler
        {
            get { return m_Battler; }
            set { m_Battler = value; }
        }

        public override int GetHashCode()
        {
            return m_Location.GetHashCode();
        }

        private Vector2Int m_Location;

        public Vector2Int Location
        {
            get { return m_Location; }
        }
        
        public int X
        {
            get { return m_Location.X; }
        }

        public int Y
        {
            get { return m_Location.Y; }        
        }

        public Vector2 RealLocation
        {
            get { return m_Location * m_Map.TileSize + m_Map.TileSize / 2; }
        }

        public int GetGridDistTo(BattleTile other)
        {
            return Math.Max(Math.Abs(other.X - X), Math.Abs(other.Y - Y));
        }

        public bool IsBlocked(Battler battler)
        {
            if (Battler != null && Battler != battler)
                return true;
            
            return false;
        }


        #region IMapNode<BattleTile> Members

        public IEnumerable<BattleTile> Neighbours
        {
            get 
            {
                BattleTile[] tiles;
                m_Map.GetAdjacentTiles(m_Location.X, m_Location.Y, out tiles);

                foreach (BattleTile tile in tiles)
                {
                    if (tile != null)
                    {
                        yield return tile;
                    }
                }
            }
        }

        public float GetCostTo(BattleTile node)
        {
            return Vector2Int.Distance(this.Location, node.Location);
        }

        public bool CanEnter()
        {
            return Battler == null;
        }

        public Vector3 Position
        {
            get { return new Vector3(m_Location.X, m_Location.Y, 0.0f); }
        }

        public bool Equals(BattleTile other)
        {
            return this == other;
        }

        #endregion
    }
}
